package com.dfd.consumer.hsbtest;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author 胡帅博
 * @date 2023/9/16 21:18
 */
public class Demo1 {
    public static void main(String[] args) {

        //没有队列，直接交给线程执行
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1, 21, 1L, TimeUnit.MINUTES, new SynchronousQueue<>());

        List<Task> taskList = new CopyOnWriteArrayList<Task>();

        //模拟2w任务
        for (int i = 0; i < 20000; i++) {
            taskList.add(new Task(i));
        }

        poolExecutor.submit(new DispatchTask(poolExecutor, taskList));

    }
}

//任务的封装，比如一条mq的消息
class Task {
    int id;

    public Task(int id) {
        this.id = id;
    }
}

//任务调度线程
class DispatchTask implements Runnable {


    ThreadPoolExecutor poolExecutor;
    List<Task> taskList;

    public DispatchTask(ThreadPoolExecutor poolExecutor, List<Task> taskList) {
        this.poolExecutor = poolExecutor;
        this.taskList = taskList;
    }

    @Override
    public void run() {

        int lowTaskLimit = 10;
        int highTaskLimit = 20;

        while (true) {
            //8-24点  最多10个线程
            //24-8点 最多20个线程

            //int hour = LocalDateTime.now().getHour();

            int hour = (int) (( (System.currentTimeMillis()/1000) *0.2) % 24);  //按照5秒为一小时来处理

            System.out.println("当天时间点(小时)："+ hour);
            int activeCount = poolExecutor.getActiveCount();
            System.out.println("当前运行中线程数量："+ activeCount);
            int maxTaskCount = 0;
            if (hour >= 8 && hour < 24 && activeCount < lowTaskLimit) {
                //低任务水平
                maxTaskCount = lowTaskLimit;

            } else if (hour < 8 && activeCount < highTaskLimit) {
                //高任务水平
                maxTaskCount = highTaskLimit;
            }
            System.out.println("当前时间点可执行的最大任务数："+ maxTaskCount);
            boolean hasTask=false;
            while ((++activeCount) <= maxTaskCount && (hasTask=addTaskToPool())) {

                if (!hasTask){
                    //没有任务了，退出循环，休眠
                    break;
                }
            }

            try {
                if (hasTask){
                    //可能还有待执行任务，睡眠时间短一点
                    Thread.sleep(16);
                }else {
                    Thread.sleep(1000);//当前没有可执行任务栏，多睡眠一会
                }


            } catch (Exception e) {
                e.printStackTrace();
            }


        }

    }

    /**
     * @return true:添加成功 false:没有任务了
     */
    public boolean addTaskToPool() {
        Task task = getTask();
        if (task == null) {
            //没有任务了
            return false;
        } else {
            poolExecutor.execute(new TaskRunnable(task));
            return true;
        }
    }

    /**
     * 获取下一个任务，比如从数据库拿，从redis拿，从java队列拿任务
     */
    public Task getTask() {
        if (taskList.size() == 0) {
            return null;
        } else {
            Task remove = taskList.remove(0);
            return remove;
        }

    }


}


//具体的任务执行线程
class TaskRunnable implements Runnable {


    Task task;

    public TaskRunnable(Task task) {
        this.task = task;
    }

    @Override
    public void run() {
        // 模拟任务执行时长5秒
        try {
            System.out.println("执行任务："+task.id);
            ThreadLocalRandom current = ThreadLocalRandom.current();

            Thread.sleep(current.nextInt(3000)+2000);  //模拟睡眠2-5秒
           // Thread.sleep(current.nextInt(4000);  //模拟睡眠4秒

            //todo 执行完成后，比如要删除数据库中数据，redis中数据等
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

